<?php

namespace App\Models\Traits;

use App\Exceptions\VoteException;
use App\Models\User;
use Illuminate\Support\Carbon;

trait PlayerAction
{
    public function isShowable(): bool
    {
        return $this->isEnabled() && $this->chapter->isEnabled() && $this->season->isEnabled() && $this->application->isEnabled();
    }

    /**
     * Notes   : 点赞
     *
     * @Date   : 2024/7/24 上午9:47
     * @Author : <Jason.C>
     * @param  User  $user
     * @return bool
     * @throws VoteException
     */
    public function giveLike(User $user): bool
    {
        $this->isVotable($user);

        if (!$this->season->config['show_comment']) {
            throw new VoteException('当前活动不允许点赞');
        }

        if ($this->season->config['time_check_type'] == 'day') {
            if ($this->likes()->where('user_id', $user->getKey())->whereDate('created_at', Carbon::today())->exists()) {
                throw new VoteException('今日已点赞', 4001);
            }
        } else {
            $latest = $this->likes()->where('user_id', $user->getKey())->orderByDesc('id')->first();
            if ($latest && Carbon::now()->diffInHours($latest->created_at) < 24) {
                throw new VoteException('24小时内只可点赞一次', 4001);
            }
        }

        $this->likes()->create([
            'application_id' => $this->application_id,
            'season_id' => $this->season_id,
            'chapter_id' => $this->chapter_id,
            'user_id' => $user->getKey(),
            'polls' => $this->season->config['like_polls'],
        ]);

        return true;
    }

    /**
     * @throws VoteException
     */
    public function isVotable(User $user): void
    {
        if ($user->lock) {
            throw new VoteException('您无法操作，请稍候再试');
        }

        if ($this->isDisabled()) {
            throw new VoteException('选手不存在');
        }

        # region 活动场次的判断
        if ($this->chapter->isDisabled()) {
            throw new VoteException('活动场次不可操作');
        }

        if (!Carbon::now()->between($this->chapter->start_at, $this->chapter->end_at)) {
            if (Carbon::now()->lt($this->chapter->start_at)) {
                throw new VoteException('本场活动未开始');
            }
            if (Carbon::now()->gt($this->chapter->end_at)) {
                throw new VoteException('本场活动已结束');
            }
        }
        # endregion

        # region 赛季的判断
        if ($this->season->isDisabled()) {
            throw new VoteException('本轮赛季已失效');
        }
        # endregion

        # region 应用判断
        if ($this->application->isDisabled()) {
            throw new VoteException('应用已失效');
        }
        if (Carbon::now()->gt($this->application->expired_at)) {
            throw new VoteException('应用已过期');
        }
        # endregion
    }

    /**
     * @throws VoteException
     */
    public function giveComment(User $user, string $content): bool
    {
        $this->isVotable($user);

        if (!$this->season->config['show_comment']) {
            throw new VoteException('当前活动不允许评论');
        }

        if ($this->season->config['time_check_type'] == 'day') {
            if ($this->comments()->where('user_id', $user->getKey())->whereDate('created_at',
                Carbon::today())->exists()) {
                throw new VoteException('今日已评论', 4001);
            }
        } else {
            $latest = $this->comments()->where('user_id', $user->getKey())->orderByDesc('id')->first();
            if ($latest && Carbon::now()->diffInHours($latest->created_at) < 24) {
                throw new VoteException('24小时内只可评论一次', 4001);
            }
        }

        $this->comments()->create([
            'application_id' => $this->application_id,
            'season_id' => $this->season_id,
            'chapter_id' => $this->chapter_id,
            'user_id' => $user->getKey(),
            'content' => $content,
            'polls' => $this->season->config['comment_polls'],
        ]);

        return true;
    }

    public function getWechatId(): int
    {
        return $this->chapter->wechat_id ?? $this->chapter->season->wechat_id;
    }

    public function getPaymentId(): int
    {
        return $this->chapter->wechat?->payment_id ?? $this->chapter->season->wechat->payment_id;
    }
}
